/*  
     PlAr is Platform Arena: a 2D multiplayer shooting game
     Copyright (C) 2009 Ragagnin Antonio <spocchio@gmail.com>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package plar.core;

import java.util.*;

import java.awt.Point;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import org.jbox2d.dynamics.World; 

import org.jbox2d.common.*;

import org.jbox2d.collision.*;
import org.jbox2d.collision.Shape;
import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.Body;

import plar.ClientServer.ShownElement;

public class Game {

	private int gamestate;
	public Parameters info;
	public Level level;
	private ArrayList <String> chat;
	public Point screenResolution;
	public Vec2 gameResolution;
	
	public Game() {
		info = new Parameters();
		info.put("life", 100);
		screenResolution = new Point(800, 600);
		gameResolution = new Vec2(13f,13.2f*3f/4f);
		chat = new ArrayList <String>();
		for(int i =0;i<10;i++) chat.add("");
	}

	public void addPlayer(Player s) {
		spawn(s);
	}


	public ArrayList<ShownElement> getScreen(Player currentPlayer) {
		
		Vec2 curpos = new Vec2 (currentPlayer.getPosition().x,currentPlayer.getPosition().y);
		Vec2 gameScreen=new Vec2();
		gameScreen.x = curpos.x - gameResolution.x / 2;
		gameScreen.y = curpos.y - gameResolution.y / 2;
		ArrayList <Element> inside = level.getScreen(gameScreen,gameResolution);
		ArrayList <ShownElement> se = new ArrayList  ();
		Vec2 scale = new Vec2();
		
		scale.x=((float)(screenResolution.x))/gameResolution.x;
		scale.y=((float)(screenResolution.y))/gameResolution.y;
		Collections.reverse(inside);

		for (Element e : inside) {
			
			
		//	Common.info("in screen: "+r);
			ArrayList<Sprite> cs=new ArrayList<Sprite>();
			for(Sprite s:e.getCurrentSpriteSet())
			{
				Sprite ns = new Sprite(s.time);
				ns.filename=s.filename;
				ns.texturized=s.texturized;
				ns.offsetx=scale.x*s.offsetx;
				ns.offsety=scale.y*s.offsety;
				ns.sizex=scale.x*s.sizex;
				ns.sizey=scale.y*s.sizey;
				//if(e.getProperty("type").equals("pack"))
				//Common.info(7,""+ns.visible);
				if(s.visible==false)
				{
					 scale.x=scale.y=0;
					 Common.info(5,"Game., found a non visible sprite!");
				 }
				cs.add(ns);
			}
			
			Rectangle r = new Rectangle(
					(int)(scale.x*(e.getPosition().x-gameScreen.x-e.getSize().x/2)),
					(int)(scale.y*(e.getPosition().y-gameScreen.y-e.getSize().y/2)),
					(int)(scale.x*e.getSize().x),
					(int)(scale.y*e.getSize().y));
			se.add(new ShownElement(r, cs));
			}
		return se;

	}

	public void spawn(Player p) {
		sendChat(p,"respawn!");
		p.gl.clear();		
		p.gl.add(new res.elements.GunQueen(p));
		p.gl.add(new res.elements.GunRage(p));
		p.gl.add(new res.elements.GunMine(p));
		p.setProperty("currentGun", 0);

		ArrayList <Element> al =(ArrayList <Element>)level.getElementsByType("spawn");
		int rand=(int)(Math.random()*1000);
		rand=rand%al.size();
		Element spawn = al.get(rand);
		Common.info(5,"Game.spawn(): "+spawn.getPosition()+" of "+al.size()+" dado:"+rand);
		p.setPosition(spawn.getPosition().x+0.5f,spawn.getPosition().y);
		info.put("me", p);
		info.put("life", 100);
		info.put("subAction", "force");
		p.actions.runAction("born", info);
		
		level.AddElement(p);
		((ArrayList<Gun>) (p.getProperty("gunList"))).get(0).addAmmo(10);
		
            
	}
		

	

	public void run() {
	
		if (gamestate != 1)
			return;

		// check who died and add it to the dead list
		List<Player> currentplayers = (ArrayList) level.getPlayers();
		for (Player p : currentplayers) {
			if ((Integer) p.getProperty("energy") <= 0) {
				Common.info(3,""+p+" have a negative energy");
				level.delElement(p);
			//	level.AddElement(p);
				spawn(p);
			}
		}

	
		level.run();
		

	}

	public void sendInput(Player p, ArrayList<String> premuti) {
		Parameters input = new Parameters();
		input.put("key", premuti);
		input.put("me", p);
		input.put("level", level);
		input.put("subAction", "input");
		p.actions.runAction("input", input);

	}

	public boolean setLevel(Level l) {
		
		AABB worldAABB = new AABB();
		worldAABB.lowerBound=new Vec2(0,0);
		worldAABB.upperBound=new Vec2(l.dim.x,l.dim.y);
		l.world = new World(worldAABB,l.g,true);
		Common.info(1,"Loading level... of dimension"+l.dim+" and force"+l.g);
		l.Initialize();
		info = new Parameters();
		info.put("subAction", "main");
		if (gamestate == 0)
			level = l;
		info.put("level", level);
		return true;
	}

	public void sendChat(Player p, String s)
	{
		Calendar cal = new GregorianCalendar();
		 int ore = cal.get(Calendar.HOUR);
		int minuti = cal.get(Calendar.MINUTE);
		int secondi = cal.get(Calendar.SECOND);
		String nick = (String) p.getProperty("user");
		chat.add(chat.size()-1,"["+ore+":"+minuti+":"+secondi+"] "+nick+"> "+s);
		chat.remove(0);
	}
	
	public void sendChat(String s)
	{
		 Calendar cal = new GregorianCalendar();
		 int ore = cal.get(Calendar.HOUR);
		int minuti =cal.get(Calendar.MINUTE);
		int secondi = cal.get(Calendar.SECOND);

		chat.add(chat.size()-1,"["+ore+":"+minuti+":"+secondi+"] * "+s);
		chat.remove(0);
	}
	
	public String getChat(Player p)
	{
		String s=new String();
		int energy = (Integer) p.getProperty("energy");
		String name = (String) p.getProperty("user");
		 for(int i = 0;i<chat.size();i++) s+=chat.get(i)+"\n";
		 s+="\n"+name+" energy: "+energy;
		 int sel = p.getCurrentGun();
		 for(int i = 0;i<p.gl.size();i++)
		 {
			 Gun g = p.gl.get(i);
			 if(sel!=i)
			 s+="\n"+g.getGunName()+": "+g.getAmmo()+"ammo";
			 else
			 s+="\n["+g.getGunName()+": "+g.getAmmo()+" ammo]";
		 }
		 return s;
	}
	public void startGame() {
		if (gamestate != 0) return;
		gamestate++;
	}

}
